package org.lionsoul.websnail.util;

import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.util.ArrayList;
import java.util.List;

/**
 * 链接提取器的默认实现
 *
 * @author yangjian
 */
public class DefaultLinkExtractor implements LinkExtractor {

    // 清除 HTTPS 链接
    public static final int LINK_CLEAR_HTTPS = 1;
    // 清除外部链接（非本站链接）
    public static final int LINK_CLEAR_EXTERNAL = 1 << 2;
    // 清除链接中的锚点
    public static final int LINK_CLEAR_ANCHOR = 1 << 3;
    private String html = null;
    private String url = null;

    // 导出链接选项设置
    private int optionMask = LINK_CLEAR_EXTERNAL | LINK_CLEAR_ANCHOR;


    public static DefaultLinkExtractor create() {
        return new DefaultLinkExtractor();
    }

    @Override
    public String[] extract() {
        //parse the html and get the links
        Document doc = Jsoup.parse(html, url);
        //get all the links
        Elements links = doc.select("a[href]");

        int startPos = url.indexOf("://");
        int endPos = url.indexOf('/', startPos + 4);
        Host baseHost = WebUtils.getHost(url);

        List<String> linkList = new ArrayList<>();
        for (Element link : links) {
            String href = link.attr("href").toLowerCase();
            if (StringUtils.isBlank(href)) {
                continue;
            }

            href = href.trim().toLowerCase();
            //clear up the useless links
            if (href.equals("")
                    || href.startsWith("#")
                    || href.startsWith("javascript:")) {
                continue;
            }

            // 过滤 https 链接
            if ((optionMask & LINK_CLEAR_HTTPS) != 0
                    && href.startsWith("https://")) {
                continue;
            }

            // 过滤外部链接
            if ((optionMask & LINK_CLEAR_EXTERNAL) != 0) {
                Host host = WebUtils.getHost(href);
                if (null != host.getHost() && !StringUtils.equals(host.getHost(), baseHost.getHost())) {
                    continue;
                }
            }

            // 去除锚点
            if ((optionMask & LINK_CLEAR_ANCHOR) != 0) {
                int i = href.indexOf("#");
                if (i != -1) {
                    href = href.substring(0, i);
                }
            }

            // 处理相对路径
            if (!href.contains("://")) {
                href = baseHost.getScheme() + "://" + baseHost.getHost() + href;
            }

            linkList.add(href);
        }

        //load the links to a string array
        String[] linkArray = new String[linkList.size()];
        return linkList.toArray(linkArray);
    }

    @Override
    public String getHtml() {
        return html;
    }

    @Override
    public DefaultLinkExtractor setHtml(String html) {
        this.html = html;
        return this;
    }

    @Override
    public String getUrl() {
        return url;
    }

    @Override
    public DefaultLinkExtractor setUrl(String url) {
        this.url = url;
        return this;
    }

    @Override
    public int getOptions() {
        return optionMask;
    }

    @Override
    public DefaultLinkExtractor setOptions(int mask) {
        this.optionMask = mask;
        return this;
    }

    public DefaultLinkExtractor enableHttpsClear() {
        optionMask |= LINK_CLEAR_HTTPS;
        return this;
    }

    public DefaultLinkExtractor enableExternalLinkClear() {
        optionMask |= LINK_CLEAR_EXTERNAL;
        return this;
    }

    public DefaultLinkExtractor enableAnchorClear() {
        optionMask |= LINK_CLEAR_ANCHOR;
        return this;
    }
}
